#include "RpcMessage.h"

namespace Rpc{

std::atomic<uint64_t> Message::requestId_{0};

std::shared_ptr<Message> Message::createMessage(){
    auto message = std::make_shared<Message>();
    message->header_.requestId_ = requestId_++;
    return message;
}

std::shared_ptr<Message> Message::parse(const char* data, std::size_t len){
    auto header = const_cast<MessageHeader*>(reinterpret_cast<const MessageHeader*>(data));
    if(header->flag == rpcFlag){
        auto message = std::make_shared<Message>(*header, data + headerLengh, data + len - data);
        message->header_.requestId_ = requestId_++;
        return message;
    }
    else{
        return nullptr;
    }

}

Message::Message(){
    
}

Message::Message(const MessageHeader header, const char* body, std::size_t len)
        :header_(header)
{
    data_.assign(body, body + len);
}

Message::~Message(){

}

void Message::setRequestId(const uint64_t requestId){
    header_.requestId_ = requestId;
}

uint64_t Message::getRequestId() const{
    return header_.requestId_;
}

void Message::setMsg(const std::string msg){
    data_.assign(msg.begin(), msg.end());
}
void Message::setMsg(const MsgType type, const std::string msg){
    header_.type_ = type;
    data_.assign(msg.begin(), msg.end());
}

void Message::setPacketType(const PacketType type){
    header_.packetType_= type;
}
PacketType Message::getPacketType() const{
    return header_.packetType_;
}

char* Message::data() {
    char buf[18];
    buf[0] = header_.flag;
    buf[1] = header_.version_;
    buf[2] = header_.packetType_;
    *(uint64_t*)(buf+3) = header_.requestId_;
    buf[12] = header_.type_;
    *(uint32_t*)(buf+12) = header_.len_;

    std::vector<char> tmp(headerLengh + data_.size());
    tmp.assign(buf, buf + 16);
    tmp.assign(data_.begin(), data_.end());
    data_.swap(tmp);
    return data_.data();
}

void Message::setTimeOut(const std::chrono::seconds timeOut)
{
    timeOut_ = timeOut;
}

 std::chrono::seconds Message::getTimeOut() const{
     return timeOut_;
 }

}
